package cn.chiship.framework.third.biz.wxpub.service.impl;

import cn.chiship.framework.third.biz.wxpub.entity.ThirdWechatUser;
import cn.chiship.framework.third.biz.wxpub.entity.ThirdWechatUserExample;
import cn.chiship.framework.third.biz.wxpub.entity.ThirdWechatUserLocation;
import cn.chiship.framework.third.biz.wxpub.entity.ThirdWechatUserMessage;
import cn.chiship.framework.third.biz.wxpub.service.ThirdWechatUserLocationService;
import cn.chiship.framework.third.biz.wxpub.service.ThirdWechatUserMessageService;
import cn.chiship.framework.third.biz.wxpub.service.ThirdWechatUserService;
import cn.chiship.framework.third.biz.wxpub.service.WeixinService;
import cn.chiship.framework.third.core.common.ThirdConstants;
import cn.chiship.framework.third.core.common.WechatUtils;
import cn.chiship.sdk.core.base.constants.BaseConstants;
import cn.chiship.sdk.core.exception.ExceptionUtil;
import cn.chiship.sdk.core.exception.custom.BusinessException;
import cn.chiship.sdk.core.id.SnowflakeIdUtil;
import cn.chiship.sdk.core.util.StringUtil;

import cn.chiship.sdk.third.wx.core.common.WxPubCommonConstants;
import cn.chiship.sdk.third.wx.core.common.WxPubMessageTypeEnum;
import cn.chiship.sdk.third.wx.core.config.WeiXinConfig;
import cn.chiship.sdk.third.wx.core.util.WxPubMessageToXml;
import cn.chiship.sdk.third.wx.network.WxPubServicesUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import cn.chiship.sdk.core.base.BaseResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * @author lijian
 */
@Service
public class WeixinServiceImpl implements WeixinService {
    private static final Logger LOGGER = LoggerFactory.getLogger(WeixinServiceImpl.class);

    private static final String STRING_FROM_USER = "FromUserName";
    private static final String STRING_TO_USER = "ToUserName";
    private static final String STRING_MSG_TYPE = "MsgType";
    private static final String STRING_EVENT = "Event";
    private static final String STRING_EVENT_KEY = "EventKey";
    private static final String STRING_CONTENT = "Content";


    @Resource
    private ThirdWechatUserService wechatUserService;
    @Resource
    private ThirdWechatUserLocationService wechatUserLocationService;
    @Resource
    ThirdWechatUserMessageService thirdWechatUserMessageService;

    @Override
    public String analysisMessage(Map<String, String> params) {
        //发送者
        String fromUserName = params.get(STRING_FROM_USER);
        //接收者
        String toUserName = params.get(STRING_TO_USER);
        //消息类型
        String msgType = params.get(STRING_MSG_TYPE);

        String appKey = params.get("appKey");

        String appSecret = params.get("appSecret");
        String message = null;

        saveMessage(appKey, fromUserName, params);

        /**
         * 事件消息
         */
        if (WxPubMessageTypeEnum.WX_PUB_MESSAGE_EVENT.getType().equals(msgType)) {
            String eventType = params.get(STRING_EVENT);
            String eventKey = params.get(STRING_EVENT_KEY);
            /**
             * 关注事件
             */
            if (WxPubCommonConstants.MESSAGE_SUBSCRIBE.equals(eventType)) {
                message = subScribe(appKey, appSecret, fromUserName, toUserName);
            }
            /**
             * 取消关注事件
             */
            if (WxPubCommonConstants.MESSAGE_UNSUBSCRIBE.equals(eventType)) {
                unsubScribe(appKey, fromUserName);
            }

            /**
             * 获取位置
             */
            if (WxPubCommonConstants.MESSAGE_LOCATION.equals(eventType)) {
                updateLocation(appKey, fromUserName, params);
            }
        } else {
        }
        if (StringUtil.isNullOrEmpty(message)) {
            message = WxPubMessageToXml.initTextMessage(fromUserName, toUserName, "小码哥正在努力接入中...");

        }
        return message;

    }

    /**
     * 首次关注
     *
     * @param fromUserName
     * @param toUserName
     * @return
     */
    @Override
    public String subScribe(String appKey, String appSecret, String fromUserName, String toUserName) {
        WeiXinConfig weiXinConfig = new WeiXinConfig(appKey, appSecret);
        WxPubServicesUtil weiXinPubServicesUtil = WxPubServicesUtil.getInstance().config(weiXinConfig).token();
        BaseResult userResult = weiXinPubServicesUtil.getUserInfo(fromUserName);
        if (userResult.isSuccess()) {
            JSONObject userJson = (JSONObject) userResult.getData();
            //缓存openId
            ThirdWechatUser wechatUser = WechatUtils.convertJsonToWechatUser(userJson);
            wechatUser.setAppId(appKey);
            wechatUserService.saveWechatUser(wechatUser);
            return WxPubMessageToXml.initTextMessage(fromUserName, toUserName, ThirdConstants.WELCOME + userJson.getString("nickname"));
        }
        return WxPubMessageToXml.initTextMessage(fromUserName, toUserName, WxPubCommonConstants.WELCOME);
    }

    /**
     * 取消关注
     *
     * @param fromUserName
     */
    @Override
    public void unsubScribe(String appKey, String fromUserName) {
        //取消关注  更新用户状态
        ThirdWechatUser wechatUser = new ThirdWechatUser();
        wechatUser.setAppId(appKey);
        wechatUser.setOpenId(fromUserName);
        wechatUserService.updateByPrimaryKeySelective(wechatUser);
    }


    /**
     * 修改地址信息
     */
    @Override
    public void updateLocation(String appKey, String fromUserName, Map<String, String> params) {
        ThirdWechatUserLocation wechatUserLocation = new ThirdWechatUserLocation();
        wechatUserLocation.setAppId(appKey);
        wechatUserLocation.setOpenId(fromUserName);
        wechatUserLocation.setLatitude(params.get("Latitude"));
        wechatUserLocation.setLongitude(params.get("Longitude"));
        wechatUserLocation.setPrecision(params.get("Precision"));
        wechatUserLocationService.insertOrUpdateSelective(wechatUserLocation);
    }

    @Override
    public void saveMessage(String appKey, String fromUserName, Map<String, String> params) {
        String msgType = params.get(STRING_MSG_TYPE);
        params.remove("appKey");
        params.remove("appSecret");
        ThirdWechatUserMessage thirdWechatUserMessage = new ThirdWechatUserMessage();
        thirdWechatUserMessage.setAppId(appKey);
        thirdWechatUserMessage.setOpenId(fromUserName);
        thirdWechatUserMessage.setMessageType(msgType);
        thirdWechatUserMessage.setIsRead(BaseConstants.NO);
        thirdWechatUserMessage.setMessageContent(JSON.toJSONString(params));
        thirdWechatUserMessageService.insertSelective(thirdWechatUserMessage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BaseResult synchronizationUser(String appKey, String appSecret) {
        try {
            WeiXinConfig weiXinConfig = new WeiXinConfig(appKey, appSecret);
            WxPubServicesUtil weiXinPubServicesUtil = WxPubServicesUtil.getInstance().config(weiXinConfig).token();
            BaseResult userOpenIdsResult = weiXinPubServicesUtil.syncUser();
            if (userOpenIdsResult.isSuccess()) {
                ThirdWechatUserExample wechatUserExample = new ThirdWechatUserExample();
                wechatUserExample.createCriteria().andAppIdEqualTo(appKey);
                List<ThirdWechatUser> wechatUsers = wechatUserService.selectByExample(wechatUserExample);
                List<String> currentOpenIds = new ArrayList<>();
                for (ThirdWechatUser wechatUser : wechatUsers) {
                    currentOpenIds.add(wechatUser.getOpenId());
                }
                JSONObject dataJson = (JSONObject) userOpenIdsResult.getData();
                JSONArray openIds = dataJson.getJSONObject("data").getJSONArray("openid");
                String nextOpenId = dataJson.getString("next_openid");
                Integer total = dataJson.getInteger("total");
                Integer count = dataJson.getInteger("count");
                List<String> networkOpenIds = new ArrayList<>();
                for (Integer i = 0; i < openIds.size(); i++) {
                    networkOpenIds.add(openIds.getString(i));
                }

                /**
                 * 删除
                 */
                List<String> currentNotExists = new ArrayList<>(currentOpenIds);
                currentNotExists.removeAll(networkOpenIds);
                if (!currentNotExists.isEmpty()) {
                    System.out.println("删除:" + JSON.toJSONString(currentNotExists));
                }

                /**
                 * 新增
                 */
                List<ThirdWechatUser> newWeChatUsers = new ArrayList<>();
                List<String> notExists = new ArrayList<>(networkOpenIds);
                notExists.removeAll(currentOpenIds);
                if (!notExists.isEmpty()) {
                    for (String s : notExists) {
                        BaseResult userResult = weiXinPubServicesUtil.getUserInfo(s);
                        if (userResult.isSuccess()) {
                            JSONObject userJson = (JSONObject) userResult.getData();
                            ThirdWechatUser wechatUser = WechatUtils.convertJsonToWechatUser(userJson);
                            wechatUser.setAppId(appKey);
                            wechatUser.setId(SnowflakeIdUtil.generateStrId());
                            wechatUser.setIsDeleted(BaseConstants.NO);
                            wechatUser.setGmtCreated(System.currentTimeMillis());
                            wechatUser.setGmtModified(System.currentTimeMillis());
                            newWeChatUsers.add(wechatUser);
                        }
                    }
                    wechatUserService.insertSelectiveBatch(newWeChatUsers);
                }
                return BaseResult.ok();
            }
            return BaseResult.error(userOpenIdsResult.getData());
        } catch (Exception e) {
            LOGGER.error("系统错误" + e.getLocalizedMessage());
            return ExceptionUtil.formatException(e);
        }
    }
}

